package com.neurotech.pcc.ui.adapter

import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.support.v7.recyclerview.extensions.ListAdapter
import android.support.v7.util.DiffUtil
import android.support.v7.widget.RecyclerView
import android.text.TextUtils
import android.util.SparseBooleanArray
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.navigation.Navigation
import com.neurotech.pcc.R
import com.neurotech.pcc.dummy.PingCallback
import com.neurotech.pcc.dummy.RemoteModel
import com.neurotech.pcc.other.NetworkUtils
import com.neurotech.pcc.other.ThreadPool
import com.neurotech.pcc.widgets.SwipeItemLayout
import kotlinx.android.synthetic.main.fragment_main_list.view.*
import java.util.concurrent.TimeUnit

/**
 * Created by shenhua on 2018/10/12.
 * @author shenhua
 *         Email shenhuanet@126.com
 */
class MainItemAdapter : ListAdapter<RemoteModel, MainItemAdapter.ViewHolder>(RemoteDiffCallback()) {

    var deleteListener: DeleteListener? = null
    var clickListener: ClickListener? = null
    private var sparseBooleanArray = SparseBooleanArray()
    private val handler = Handler(Looper.getMainLooper())

    override fun onCreateViewHolder(parent: ViewGroup, position: Int): ViewHolder {
        return ViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.fragment_main_list, parent, false))
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val remoteModel = getItem(position)
        holder.apply {
            bind(remoteModel, sparseBooleanArray)
            clickListener(createOnClickListener(), remoteModel)
            editClick(View.OnClickListener {
                val bundle = Bundle()
                bundle.putSerializable("remoteModel", remoteModel)
                bundle.putBoolean("isEdit", true)
                Navigation.findNavController(it).navigate(R.id.action_mainFragment_to_configFragment, bundle)
                stop()
            })
            deleteClick(View.OnClickListener {
                deleteListener?.onDelete(remoteModel)
                stop()
            })
        }
    }

    private fun createOnClickListener(): ClickListener? {
        return clickListener
    }

    override fun submitList(list: List<RemoteModel>?) {
        super.submitList(list)
        ThreadPool.get().resetScheduled();
        list?.forEach {
            refresh(it)
        }
    }

    private fun refresh(item: RemoteModel) {
        ThreadPool.get().scheduled().scheduleAtFixedRate({
            NetworkUtils.ping(item.host, object : PingCallback {
                override fun result(success: Boolean) {
                    sparseBooleanArray.put(item.id!!, success)
                    handler.post { notifyDataSetChanged() }
                }
            })
        }, 1000, 4000, TimeUnit.MILLISECONDS)
    }

    /**
     * 停止实时ping
     */
    fun stop() {
        ThreadPool.get().stopScheduled()
    }

    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

        fun bind(item: RemoteModel, sparseBooleanArray: SparseBooleanArray) {
            itemView.ipTv.text = if (!TextUtils.isEmpty(item.alias)) item.alias else item.host
            itemView.macTv.text = item.mac
            if (sparseBooleanArray.get(item.id!!)) {
                itemView.iconView.online()
            } else {
                itemView.iconView.offline()
            }
        }

        fun editClick(listener: View.OnClickListener?) {
            itemView.edit.setOnClickListener(listener)
            (itemView as SwipeItemLayout).close()
        }

        fun deleteClick(listener: View.OnClickListener?) {
            itemView.delete.setOnClickListener(listener)
            (itemView as SwipeItemLayout).close()
        }

        fun clickListener(listener: ClickListener?, remoteModel: RemoteModel?) {
            itemView.root.isClickable = true
            itemView.root.setOnClickListener {
                listener?.onClick(itemView, remoteModel)
            }
        }
    }

    class RemoteDiffCallback : DiffUtil.ItemCallback<RemoteModel>() {

        override fun areItemsTheSame(oldItem: RemoteModel, newItem: RemoteModel): Boolean {
            return oldItem.id == newItem.id
        }

        override fun areContentsTheSame(oldItem: RemoteModel, newItem: RemoteModel): Boolean {
            return oldItem == newItem
        }
    }

    interface ClickListener {
        fun onClick(view: View, remoteModel: RemoteModel?)
    }

    interface DeleteListener {
        fun onDelete(remoteModel: RemoteModel)
    }
}

